package com.jic.interaction.JDVOP.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jic.interaction.JDVOP.common.utils.JdVopHttpUtil;
import com.jic.interaction.JDVOP.common.utils.JdVopRedisService;
import com.jic.interaction.JDVOP.service.JdVopGetTokenService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Auther YGH
 * @DATE 2020/11/20/16:06
 */
@Service
@Slf4j
public class JdVopGetTokenServiceImpl implements JdVopGetTokenService {


    /*时间格式*/
    private static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Value("${jdvop.client_id}")
    private String client_id;
    @Value("${jdvop.username}")
    private String username;
    @Value("${jdvop.password}")
    private String password;
    @Value("${jdvop.client_secret}")
    private String client_secret;

    @Resource
    private JdVopRedisService JdVopRedisService;

    /**
     * @Auther: YGH
     * @DATE: 2020/11/15
     * 获取 Redis中的 access_token
     * 不存在的 就获取refresh_token 去刷新 access_token
     * refresh_token 不存在  就获取最新access_token
     */

    public String getJdVopAccessToken() {
        String access_token = null;
        access_token = JdVopRedisService.getValue("JdVop_Access_Token");
        if ("".equals(access_token)) {
            log.info("数据库中不存在JdVop_Access_Token,尝试获取 JdVop_Refresh_Token 进行刷新");
             String jdVop_refresh_token = JdVopRedisService.getValue("JdVop_Refresh_Token");
            if ("".equals(jdVop_refresh_token)) {
            log.info("数据库中不存在JdVop_Refresh_Token,将进行重新获取 JdVop_Access_Token");
            String url = "https://bizapi.jd.com/oauth2/accessToken";
            Map map = new HashMap();
            String grant_type = "access_token";
            map.put("grant_type", grant_type);
            map.put("client_id", client_id);
            String timestamp = DateFormatUtils.format(System.currentTimeMillis(), TIME_FORMAT); // 当前时间 格式yyyy-MM-dd HH:mm:ss
            map.put("timestamp", timestamp);
            map.put("username", username);
            password = getMD5Str(password);
            map.put("password", password);
            String sign = client_secret + timestamp + client_id + username + password + grant_type+client_secret;
            map.put("sign", getMD5Str(sign).toUpperCase());
            String s = JdVopHttpUtil.doRequestPost(url, map);
            Map m = JSONObject.parseObject(s);
            if (m.get("success").toString().equals("false")) {
                log.error("获取token失败，错误码为{},错误信息为{} ", m.get("resultCode"), m.get("resultMessage"));
                return "获取token失败，错误码为{},错误信息为"+ m.get("resultMessage");
            }
            Map mm = JSONObject.parseObject(m.get("result").toString());
            String new_access_token = mm.get("access_token").toString();//获取到的最新的token
            String new_refresh_token = mm.get("refresh_token").toString();//获取到的最新的refresh_token
            Long expires_in = Long.parseLong(mm.get("expires_in").toString());//获取到的最新的refresh_token过期时间
            Long refresh_token_expires = Long.parseLong(mm.get("refresh_token_expires").toString());//获取到的最新的refresh_token过期时间 并转为秒
            JdVopRedisService.setValue("JdVop_Access_Token", new_access_token, expires_in); //添加 JdVop_Access_Token
            JdVopRedisService.setValue("JdVop_Refresh_Token", new_refresh_token, refresh_token_expires); //添加 JdVop_Refresh_Token
            log.info("获取到最新access_token{}", new_access_token);
            return new_access_token;
            }
            log.info("数据库中存在JdVop_Refresh_Token,将进行重新获取Access_Token");
            access_token = getJdVopRefreshToken();
        }
        return access_token;
    }

    /**
     * @Auther: YGH
     * @DATE: 2020/11/16
     * 通过 Refresh_Token  进行刷新 access_token
     * 每天的23分59秒执行
     */
    @Scheduled(cron = "0 59 23 * * ?")
    public String getJdVopRefreshToken() {
        String jdVop_refresh_token = JdVopRedisService.getValue("JdVop_Refresh_Token");
        String url = "https://bizapi.jd.com/oauth2/refreshToken";
        Map map = new HashMap();
        map.put("refresh_token", jdVop_refresh_token);
        map.put("client_id", client_id);
        map.put("client_secret", client_secret);
        String s = JdVopHttpUtil.doRequestPost(url, map);
        Map m = JSONObject.parseObject(s); //获取到的新的token map对象
        String succ = m.get("success").toString();
        if (succ == "false") {
            log.error("刷新token失败，错误码为{},错误信息为{} ", m.get("resultCode"), m.get("resultMessage"));
            return "刷新token失败，错误码为{},错误信息为"+ m.get("resultMessage");
        }
        Map mm = JSONObject.parseObject(m.get("result").toString());
        String access_token = mm.get("access_token").toString();//获取到的最新的token
        String refresh_token = mm.get("refresh_token").toString();//获取到的最新的refresh_token
        Long expires_in = Long.parseLong(mm.get("expires_in").toString());//获取到的最新的refresh_token过期时间
        Long refresh_token_expires = Long.parseLong(mm.get("refresh_token").toString());//获取到的最新的refresh_token过期时间 并转为秒
        JdVopRedisService.setValue("JdVop_Access_Token", access_token, expires_in); //添加 JdVop_Access_Token
        JdVopRedisService.setValue("JdVop_Refresh_Token", refresh_token, refresh_token_expires); //添加 JdVop_Refresh_Token
        log.info("获取到最新access_token{}", access_token);
        return access_token;
    }

    /**
     * @Auther: YGH
     * @DATE: 2020/11/15
     * MD5加密
     */
    public static String getMD5Str(String str) {
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(str.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            log.error("NoSuchAlgorithmException caught!");
            System.exit(-1);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] byteArray = messageDigest.digest();
        StringBuilder md5StrBuff = new StringBuilder();

        for (int i = 0; i < byteArray.length; i++) {
            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) {
                md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
            } else {
                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
            }
        }
        return md5StrBuff.toString();
    }


}
